/*
 * SIT_Frame.c : frame / group box
 *
 * Written by T.Pierron, Oct 17, 2006.
 */

#include "SIT_P.h"
#include <stdio.h>


void SIT_TitleHeight(SIT_Widget w, LPWSTR str, SIZE * box)
{
	HDC     hdc = GetDC(w->sw_Handle);
	HGDIOBJ old = SelectObject(hdc, w->sw_Font);

	GetTextExtentPoint32(hdc, str, wcslen(str), box);

	SelectObject(hdc, old);
	ReleaseDC(w->sw_Handle, hdc);
}

static int SIT_MeasureFrame(SIT_Widget w, APTR cd, APTR unused)
{
	LPWSTR str;
	SIZE * ret = cd;

	if (IsDef(w->sw_Title))
		UTF8ToUTF16(w->sw_Title, str)
	else
		str = w->sw_Name;

	SIT_TitleHeight(w, str, ret);
	ret->cx += w->sw_Margins[0] + w->sw_Margins[2];
	if (w->sw_MinBox.cx < ret->cx)
		w->sw_MinBox.cx = ret->cx;

	/* Layout children */
	if (SIT_LayoutWidgets(w, FitUsingOptimalBox))
	{
		ret->cx = w->sw_Box.width  - w->sw_Box.x;
		ret->cy = w->sw_Box.height - w->sw_Box.y;
		w->sw_ChildBox = *ret;
//		fprintf(stderr, "** frame '%S' sz = %ldx%ld\n", w->sw_Name, ret->cx, ret->cy);
	}

	return 0;
}

/* Usual half-assed job from Microsoft. See KB79982 */
static LRESULT CALLBACK SIT_FrameSubClassHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	SIT_Widget w    = (SIT_Widget) GetProp(hwnd, sit_class), c;
	WNDPROC    proc = (WNDPROC) GetWindowLong(hwnd, GWL_USERDATA);
	RECT       rect;
	HDC        hDC;

	switch (msg) {
	case WM_ERASEBKGND:
		{	SIT_Widget parent = (APTR) GetProp(GetParent(hwnd), sit_class);
			if (parent && parent->sw_Type == SIT_TAB)
				return CallWindowProc(proc, hwnd, msg, wParam, lParam);
		}

		hDC = (HDC) wParam;
		GetClientRect(hwnd, &rect);
		if (w->sw_Flags & SITF_GeometryChanged) return TRUE;
		/* Manually perform a WS_CLIPCHILDREN. Sigh */
		for (c = HEAD(w->sw_Children); c; NEXT(c))
			if (c->sw_Visible) {
				int right = c->sw_Box.width;
				HWND wnd;
				if (c->sw_Type == SIT_EDITBOX && (wnd = ((SIT_EditBox)c)->se_UpDown))
				{
					RECT r;
					GetWindowRect(wnd, &r);
					ScreenToClient(w->sw_Handle, (LPPOINT) &r.right);
					right = r.right;
				}
				ExcludeClipRect(hDC, c->sw_Box.x, c->sw_Box.y, right, c->sw_Box.height);
			}

		FillRect(hDC, &rect, (HBRUSH) GetClassLong(GetParent(w->sw_Handle), GCL_HBRBACKGROUND));
		InvalidateRect(hwnd, NULL, FALSE);
		return TRUE;
	case WM_DESTROY:
		SetWindowLong(hwnd, GWL_WNDPROC, (LONG) proc); // no break;
	default:
		return CallWindowProc(proc, hwnd, msg, wParam, lParam);
	}
}

/* Create and initialize a group box */
BOOL SIT_CreateFrame(SIT_Widget w, va_list args)
{
	static char margins[] = {8, 5, 8, 8};
	HWND frame;
	SIZE sz;
	int  i;

	/* Default values */
	w->sw_OptimalWidth = SIT_MeasureFrame;

	/* Default margins */
	for (i = 0; i < 4; w->sw_Margins[i] = margins[i], i ++);

	SIT_ParseTags(w, args, w->sw_Class = WidgetClass);

	frame = w->sw_Handle = CreateWindow(WC_BUTTON, w->sw_Name, WS_CHILD | WS_GROUP |
		BS_GROUPBOX | (IsVisible(w) ? WS_VISIBLE : 0), 0, 0, 10, 10,
		SIT_GetContainer(w), (HMENU) MAKE_ID(w), instance, NULL);

	SIT_TitleHeight(w, L"x", &sz);

	w->sw_Margins[1] += sz.cy - 5;

	if (frame == NULL) return FALSE;
	SIT_SetDefaultFont(w);

	if (w->sw_Title) SIT_SetTitle(w);

	/* Keep track of class inside callback */
	SetProp(frame, sit_class, (HANDLE) w);

	/* Subclass to catch WM_ERASEBACKGROUNG. Sigh.
	 * We do NOT set sw_SuperProc because SIT children are NOT win32 child of groupbox window
	 * (this will confuse the SIT_MoveWidgets() function).
	 */
	SetWindowLong(frame, GWL_USERDATA, GetWindowLong(frame, GWL_WNDPROC));
	SetWindowLong(frame, GWL_WNDPROC,  (LONG) SIT_FrameSubClassHandler);

	return TRUE;
}
